package com.giggle.restclient.util;

import java.util.*;

/**
 * @author guozichen
 * @ClassName:
 * @Description: (验签工具类)
 * @date 2020/11/12 20:15
 */
public class RestSignUtil {
    public RestSignUtil() {
    }

    public static String sign(String appkey, String url, Map<String, String> queryMap, byte[] requestBody, String privateKey) {
        byte[] signData = genSignData(appkey, url, queryMap, requestBody);

        try {
            String sign = RSAUtils.sign(signData, privateKey);
            return sign;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static byte[] genSignData(String appkey, String url, Map<String, String> queryMap, byte[] requestBody) {
        try {
            byte[] appkeyBytes = appkey.getBytes("UTF-8");
            byte[] urlBytes = url.getBytes("UTF-8");
            String queryString = queryMapToString(queryMap);
            byte[] queryStringBytes = queryString.getBytes("UTF-8");
            byte[] bytes = new byte[appkeyBytes.length + urlBytes.length + requestBody.length + queryStringBytes.length];
            System.arraycopy(appkeyBytes, 0, bytes, 0, appkeyBytes.length);
            System.arraycopy(urlBytes, 0, bytes, appkeyBytes.length, urlBytes.length);
            System.arraycopy(requestBody, 0, bytes, appkeyBytes.length + urlBytes.length, requestBody.length);
            System.arraycopy(queryStringBytes, 0, bytes, appkeyBytes.length + urlBytes.length + requestBody.length, queryStringBytes.length);
            return bytes;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static boolean verify(String appkey, String url, Map<String, String> queryMap, byte[] requestBody, String publicKey, String sign) {
        byte[] signData = genSignData(appkey, url, queryMap, requestBody);

        try {
            return RSAUtils.verify(signData, publicKey, sign);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static boolean verify(String md5String, String publicKey, String sign) {
        try {
            byte[] verifyData = md5String.getBytes("UTF-8");
            return RSAUtils.verify(verifyData, publicKey, sign);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static String queryMapToString(Map<String, String> queryMap) {
        if (queryMap.isEmpty()) {
            return "";
        } else {
            List<Map.Entry<String, String>> mappingList = new ArrayList(queryMap.entrySet());
            Collections.sort(mappingList, new Comparator<Map.Entry<String, String>>() {

                @Override
                public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                    return ((String)o1.getKey()).compareTo((String)o2.getKey());
                }
            });
            StringBuilder sf = new StringBuilder();
            Iterator iterator = mappingList.iterator();

            while(iterator.hasNext()) {
                Map.Entry<String, String> entry = (Map.Entry)iterator.next();
                sf.append((String)entry.getKey()).append(entry.getValue() == null ? "" : (String)entry.getValue());
            }

            return sf.toString();
        }
    }
}
